package com.wwe.kotlinstudy.util

import java.util.*

/**
 * @name KotlinStudy
 * @package name：com.wwe.kotlinstudy.util
 * @anthor DavidZhang
 * @time 2018/4/17 16:24
 * @class describe
 */
class FunctionStudy {

    fun printSum1(a: Int = 1, b: Int = 1): Unit {
        println("sum of $a and $b is ${a + b}")
    }

    fun printSum2(a: Int = 1, b: Int = 1) = println("sum of $a and $b is ${a + b}")

    fun test1() {
        var result = printSum1()
        println(result)

        var result2 = printSum1(a = 3)
        println(result2)
    }

    /**变长参数用vararg修饰*/
    fun <T> asList(vararg args: T): List<T> {
        val result = LinkedList<T>() //定义一个空的集合
        for (a in args)
            result.add(a)
        return result
    }

    fun test2() {
        var result = asList(1, 2, 3, 4)
        println(result)
    }

    fun <T> asList(vararg args: T, last: T): List<T> {
        val result = ArrayList<T>()
        for (a in args)
            result.add(a)
        result.add(last)
        return result
    }

    fun test3() {
        var result = asList(1, 2, 3, 4, last = 100)
        println(result)
    }

    fun <T> asRerurnList(vararg args: T, last: T): List<T> {
        val result = ArrayList<T>()
        for (a in args)
            result.add(a)
        result.add(last)
        return result
    }

    fun test4() {
        var result = asRerurnList(1, 2, 3, 4, last = 100)
        println(result)

        var temp = arrayOf(1, 2, 3, 4, 5, 6)
        result = asRerurnList(*temp, last = 100)
        println(result)
    }

    fun printSum(a: Int, b: Int): Unit {
        println("sum of $a and $b is ${a + b}")
    }

    fun test5(): Unit {
        var result = printSum(b = 2, a = 1);
        println(result)
    }

    /**局部成员函数*/
    fun sum(a: Int, b: Int): Int {
        fun localSum(a: Int, b: Int): Int {
            return a + b
        }
        return localSum(a, b)
    }

    /**成员函数：是指定义在类或对象之内的函数。*/
    //Sample().foo() 创建 Sample 类的实例, 并调用 foo 函数
    class Sample() {
        fun foo() {
            print("Foo")
        }
    }

    //扩展函数进阶，请学习

    //尾递归函数
    tailrec fun plus(start: Int, end: Int, result: Int): Int =
            if (start < end) plus(start + 1, end, start + result) else result

    //上面的代码等价于
    fun plus2(start: Int, end: Int, result: Int): Int {
        var res = result
        var sta = start

        while (sta < end) {
            res += sta
            sta++
        }

        return res
    }

    //高阶函数：它接受函数作为参数, 或者返回一个函数
    //(Int, Int) -> Int 这是一个函数
    fun sum(a: Int, b: Int, realSum: (Int, Int) -> Int): Int {
        return realSum(a, b)
    }

    //Lambda 表达式的完整语法形式, 也就是, 函数类型的字面值, 如下: val sum = { x: Int, y: Int -> x + y }
    //如果Lambda 表达式只有一个参数,隐含地定义这个参数, 使用的参数名为 it：
    //上面的代码等价于下面的代码，如果一个函数接受另一个函数作为它的最后一个参数, 那么Lambda表达式作为参数时, 可以写在圆括号之外。
    fun test6() {
        val result = sum(2, 3) { a, b ->
            a + b
        }
        println(result)
    }

}